package cn.tyz.kotlin.ui

import android.os.Bundle
import android.util.Log
import cn.tyz.kotlin.R

/**
 * @author : tyz
 * @ClassName: Note01DataType
 * @Description:Kotlin学习笔记（一） 基本数据类型
 * @time 2018/5/20 14:55
 *
 * Kotlin提供了以下的内置类型表示数字:
    Type	Bit Width
    Double	64
    Float	32
    Long	64
    Int	32
    Short	16
    Byte	8
    由于不同的表达方式，在Kotlin中较小的数字类型并不是较大的数字类型的子类型， 因此较小的数字类型
    不能隐式转化为较大的数字类型，也就是说在不进行显式转化的情况下，我们不能把一个Byte类型值赋值给一个Int变量

    每个数字类型都支持如下的转换
    toByte()：Byte       toShort()：Short         toInt()：Int
    toLong()：Long       toFloat()：Float         toDouble：Double

完整的位运算列表（只用于Int，Long）:
    shl(bits)：有符号左移（Java的<<）
    shr(bits)：有符号右移（Java的>>）
    ushr(bits)：无符号右移（Java的>>>）
    and(bits)：位与
    or(bits)：位或
    xor(bits)：位异或
    inv()：位非

字符
字符类型用Char表示，不能直接当作数字
字符字面值用单引号括起来：'1'。特殊字符可以用反斜杠转义。
Kotlin支持的转移序列：\t、 \b、\n、\r、\'、\"、\\ 和 \$。转移其他字符要用Unicode系列转移语法：'\uFF00'。

数组
数组类型用Array表示，定义了get()，set()成员函数和size成员属性，以及其它一些有用的成员函数。


 */
class Note01DataType : BaseActivity(){
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.act_common)
        showNote()
        char2Int('A')
        showArray()
    }

    fun  showNote(){
        val b:Byte=1
//        val c:Int=b   //错误 不能隐式把一个Byte类型转化为Int类型
        val c:Int=b.toInt() //显式转换来拓宽数字
        val l=1L+3  //Long+Int=>Long 缺乏隐式类型转换并不显著，因为类型会从上下文中判断出来

        Log.i("Note01DataType", "显式把字符转换为Int类型："+c.toInt())

        Log.i("Note01DataType", "字符串")
        val s = "Hello World"
        // Kotlin 中String可以视为为一个 CharArray 对象; 在这里，Kotlin 编译器会把 c 自动推断为 Char 类型。
        for(c in s)         Log.i("Note01DataType", "字符  $c")
    }



    fun sum(a: Int, b: Int): Int {  // 返回类型Int 可以省略
        return a + b
    }
    //  sum 等价于 sum2
    fun sum2(a: Int, b: Int) = a + b

    fun maxOf(a: Int, b: Int): Int? {
        if (a > b) {
            return a
        } else {
            return b
        }
    }
    // maxOf 等价于 maxOf2
    fun maxOf2(a: Int, b: Int) = if (a > b) a else b

    fun parseInt(str: String): Int? {  //?表示可以是控制 null
        return str.toIntOrNull()
    }


    /** 可以显式把字符转换为Int类型：*/
    fun char2Int(c: Char): Int {
        if (c in '0'..'9') {
            throw IllegalArgumentException("out of range");
        }
        Log.i("Note01DataType", "显式把字符转换为Int类型："+c.toInt())
        return c.toInt()
    }

    /** 创建数组并赋值的几种方式：
    1.使用库函数 arrayOf() 来创建一个数组并传递元素值给它，这样 arrayOf(1, 2, 3) 创建了 array [1, 2, 3]。
    2.库函数 arrayOfNulls() 可以用于创建一个指定大小、元素都为空的数组。
    3.用接受数组大小和一个函数参数的工厂函数，用作参数的函数能够返回给定索引的每个元素初始值：
     ① arrayOf() 函数。 ② emptyArray() 函数。 ③ arrayOfNulls() 函数
    ④ 不使用 Array 类, 使用装箱操作比如, 对于 Int 类型数组, 使用 IntArray 类替代 Array<Int> 类：
     */
    fun showArray(){
        Log.i("Note01DataType", "创建数组并赋值的几种方式：")
        val arrayA:Array<Int> = arrayOf(1,2,3)  // [1,2,3]
        Log.i("Note01DataType", "arrayOf()  arrayOf(1,2,3) "+arrayA.sum())
        val fixedSizeArray = arrayOfNulls<Int>(5)
        Log.i("Note01DataType", "arrayOfNulls()  arrayOfNulls<Int>(5) "+fixedSizeArray.size)
        val emptyArray1: Array<String?> = emptyArray()
        Log.i("Note01DataType", "emptyArray()  emptyArray() "+emptyArray1?.size)
        val emptyArray2 = arrayOfNulls<String?>(0)
        Log.i("Note01DataType", "emptyArray()  emptyArray() "+emptyArray2?.size)
        val d:Array<Int> = Array(3,{i->i*i})//[0,1,4]
        Log.i("Note01DataType", "工厂函数  Array(3,{i->i*i}) "+d?.size)
//        ④ 不使用 Array 类
        val arr = arrayOf(1, 2, 3)
        val intArr = intArrayOf(1, 2, 3)    //同理还有 booleanArrayOf() 等
        Log.i("Note01DataType", "intArrayOf() "+intArr?.toString())
    }
}